import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';
import { RootState, AppThunk } from '../../app/store';
import { fetchTicket } from './indexApi';
import type { ChannelProps } from './components/channel/index';
// import { ListItemProps, TrainQuery } from './types';
import type { TicketQuery } from '../query/types';

export interface TicketState {
  data: {
    detail: {
      departTimeStr: string;
      arriveTimeStr: string;
      arriveDate: number | null;
      durationStr: string | null;
    };
    candidates: ChannelProps[];
    // trainType: string;
    // depStation: string;
    // arrStation: string;
  };
  status: 'idle' | 'loading' | 'failed' | 'success';
}

const initialState: TicketState = {
  data: {
    detail: {
      departTimeStr: '',
      arriveTimeStr: '',
      arriveDate: null,
      durationStr: null,
    },
    candidates: [],
  },
  status: 'idle',
};

// The function below is called a thunk and allows us to perform async logic. It
// can be dispatched like a regular action: `dispatch(incrementAsync(10))`. This
// will call the thunk with the `dispatch` function as the first argument. Async
// code can then be executed and other actions can be dispatched. Thunks are
// typically used to make async requests.
export const getTicketAsync = createAsyncThunk(
  'ticket/fetchTicketList',
  async (queryParams: TicketQuery) => {
    const response: any = await fetchTicket(queryParams);
    // The value we return becomes the `fulfilled` action payload
    return response.data;
  }
);

export const ticketSlice = createSlice({
  name: 'ticket',
  initialState,
  // The `reducers` field lets us define reducers and generate associated actions
  reducers: {
    increment: (state) => {
      // Redux Toolkit allows us to write "mutating" logic in reducers. It
      // doesn't actually mutate the state because it uses the Immer library,
      // which detects changes to a "draft state" and produces a brand new
      // immutable state based off those changes
      // state.value += 1;
    },
    decrement: (state) => {
      // state.value -= 1;
    },
    // Use the PayloadAction type to declare the contents of `action.payload`
    incrementByAmount: (state, action: PayloadAction<number>) => {
      // state.value += action.payload;
    },
  },
  // The `extraReducers` field lets the slice handle actions defined elsewhere,
  // including actions generated by createAsyncThunk or in other slices.
  extraReducers: (builder) => {
    builder
      .addCase(getTicketAsync.pending, (state) => {
        state.status = 'loading';
      })
      .addCase(getTicketAsync.fulfilled, (state, action) => {
        state.status = 'success';
        const { detail, candidates } = action.payload.data;
        state.data.detail = detail;
        state.data.candidates = candidates;
      })
      .addCase(getTicketAsync.rejected, (state) => {
        state.status = 'failed';
      });
  },
});

// export const { increment, decrement, incrementByAmount } = counterSlice.actions;

// The function below is called a selector and allows us to select a value from
// the state. Selectors can also be defined inline where they're used instead of
// in the slice file. For example: `useSelector((state: RootState) => state.counter.value)`
export const selectTicket = (state: RootState) => state.ticket.data;

// We can also write thunks by hand, which may contain both sync and async logic.
// Here's an example of conditionally dispatching actions based on current state.
// export const incrementIfOdd =
//   (amount: number): AppThunk =>
//   (dispatch, getState) => {
//     const currentValue = selectCount(getState());
//     if (currentValue % 2 === 1) {
//       dispatch(incrementByAmount(amount));
//     }
//   };

export default ticketSlice.reducer;
